home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 4: GNU Archives / Linux Cubed Series 4 - GNU Archives.iso / gnu / fontutil.6 / fontutil / fontutils-0.6 / lib / xgetcwd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-03-27  |  3.0 KB  |  105 lines

  1. /* xgetcwd.c: a from-scratch version of getwd.  Based on the tcsh 5.20
  2.    source, apparently uncopyrighted.
  3.  
  4. Copyright (C) 1992 Free Software Foundation, Inc.
  5.  
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2, or (at your option)
  9. any later version.
  10.  
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #include "config.h"
  21. #include "c-pathmx.h"
  22.  
  23. #include "dirio.h"
  24. #include "xstat.h"
  25.  
  26. /* Return the pathname of the current directory, or give a fatal error.  */
  27.  
  28. string
  29. xgetcwd ()
  30. {
  31.   /* If the system provides getwd, use it.  But don't use getcwd;
  32.      forking a process is even more expensive than all the stat calls we
  33.      make figuring out the cwd.  */
  34. #ifdef GETWD_MISSING /* whole function */
  35.   struct stat root_stat, cwd_stat;
  36.   string cwd_path = xmalloc (1);
  37.   
  38.   *cwd_path = 0;
  39.   
  40.   /* Find the inodes of the root and current directories.  */
  41.   root_stat = xstat ("/");
  42.   cwd_stat = xstat (".");
  43.  
  44.   /* Go up the directory hierarchy until we get to root, prepending each
  45.      directory we pass through to `cwd_path'.  */
  46.   while (!SAME_FILE_P (root_stat, cwd_stat))
  47.     {
  48.       struct dirent *e;
  49.       DIR *parent_dir;
  50.       boolean found = false;
  51.       
  52.       xchdir ("..");
  53.       parent_dir = xopendir (".");
  54.  
  55.       /* Look through the parent directory for the entry with the same
  56.          inode, so we can get its name.  */
  57.       while ((e = readdir (parent_dir)) != NULL && !found)
  58.         {
  59.           struct stat test_stat = xlstat (e->d_name);
  60.           
  61.           if (SAME_FILE_P (test_stat, cwd_stat))
  62.             {
  63.               /* We've found it.  Prepend the pathname.  */
  64.               string temp = cwd_path;
  65.               cwd_path = concat3 ("/", e->d_name, cwd_path);
  66.               free (temp);
  67.               
  68.               /* Set up to test the next parent.  */
  69.               cwd_stat = xstat (".");
  70.               
  71.               /* Stop reading this directory.  */
  72.               found = true;
  73.             }
  74.         }
  75.       if (!found)
  76.         FATAL2 ("No inode %d/device %d in parent directory",
  77.                 cwd_stat.st_ino, cwd_stat.st_dev);
  78.       
  79.       xclosedir (parent_dir);
  80.     }
  81.   
  82.   /* If the current directory is the root, cwd_path will be the empty
  83.      string, and we will have not gone through the loop.  */
  84.   if (*cwd_path == 0)
  85.     cwd_path = "/";
  86.   else
  87.     /* Go back to where we were.  */
  88.     xchdir (cwd_path);
  89.  
  90.   return cwd_path;
  91.  
  92. #else /* not GETWD_MISSING */
  93.  
  94.   string path = xmalloc (PATH_MAX + 1);
  95.   
  96.   if (getwd (path) == 0)
  97.     {
  98.       fprintf (stderr, "getwd: %s", path);
  99.       exit (1);
  100.     }
  101.   
  102.   return path;
  103. #endif /* not GETWD_MISSING */
  104. }
  105.